﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace TouchControls
{    
    public class TouchMenu : ItemsControl
    {
        public delegate void OnMenuHandler(object sender, EventArgs args);

        public event OnMenuHandler OnMenuOpening;

        private TouchMenuContainer _container;

        public double MenuTileSize
        {
            get { return (double)GetValue(MenuTileSizeProperty); }
            set { SetValue(MenuTileSizeProperty, value); }
        }

        public double IconSize
        {
            get { return (double)GetValue(IconSizeProperty); }
            set { SetValue(IconSizeProperty, value); }
        }

        public static readonly DependencyProperty IconSizeProperty =
            DependencyProperty.Register("IconSize", typeof(double), typeof(TouchMenu), null);

        public double IconOpacity
        {
            get { return (double)GetValue(IconOpacityProperty); }
            set { SetValue(IconOpacityProperty, value); }
        }

        public static readonly DependencyProperty IconOpacityProperty =
            DependencyProperty.Register("IconOpacity", typeof(double), typeof(TouchMenu), new PropertyMetadata(1.0));
        
        public BitmapSource Icon
        {
            get { return (BitmapSource)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        public static readonly DependencyProperty IconProperty =
            DependencyProperty.Register("Icon", typeof(BitmapSource), typeof(TouchMenu), null);

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TouchMenu), new PropertyMetadata(null, TextChanged));

        private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var menu = d as TouchMenu;
            if (string.IsNullOrEmpty(menu.Text))
                menu.TextVisibility = Visibility.Collapsed;
            else
                menu.TextVisibility = Visibility.Visible;
        }

        public Visibility TextVisibility
        {
            get { return (Visibility)GetValue(TextVisibilityProperty); }
            set { SetValue(TextVisibilityProperty, value); }
        }

        public static readonly DependencyProperty TextVisibilityProperty =
            DependencyProperty.Register("TextVisibility", typeof(Visibility), typeof(TouchMenu), new PropertyMetadata(Visibility.Collapsed));        

        public Thickness Padding
        {
            get { return (Thickness)GetValue(PaddingProperty); }
            set { SetValue(PaddingProperty, value); }
        }

        public static readonly DependencyProperty PaddingProperty =
            DependencyProperty.Register("Padding", typeof(Thickness), typeof(TouchMenu), null);
        

        /// <summary>
        /// Timeout of menu in seconds
        /// </summary>
        public double Timeout
        {
            get { return (double)GetValue(TimeoutProperty); }
            set { SetValue(TimeoutProperty, value); }
        }

        public static readonly DependencyProperty TimeoutProperty =
            DependencyProperty.Register("Timeout", typeof(double), typeof(TouchMenu), new PropertyMetadata(4.0));

        public static readonly DependencyProperty MenuTileSizeProperty =
            DependencyProperty.Register("MenuTileSize", typeof(double), typeof(TouchMenu), new PropertyMetadata(70.0));   

        static TouchMenu()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TouchMenu), new FrameworkPropertyMetadata(typeof(TouchMenu)));
        }

        protected override void OnTouchDown(TouchEventArgs e)
        {
            base.OnTouchDown(e);
            this.ShowMenu(this);
            e.Handled = true;
        }

        public void ShowMenu(FrameworkElement trigger)
        {
            var adornment = AdornmentGrid.For(trigger);
            this.PrepareContainer();
            this._container.SetContext(trigger);
            
            if (OnMenuOpening != null)
                OnMenuOpening(_container, new EventArgs());

            this._container.AddToAdornment(adornment, trigger);
        }

        private void PrepareContainer()
        {
            if (this._container == null)
            {
                this._container = new TouchMenuContainer();
                this._container.MenuTileSize = this.MenuTileSize;
                this._container.Timeout = this.Timeout;
                this._container.ParentMenu = this;
                while (this.Items.Count > 0)
                {
                    var elt = this.Items[0];
                    this.Items.Remove(elt);
                    this._container.Items.Add(elt);
                }
            }
            else
            {
                foreach (var elt in this._container.Items)
                {
                    var menu = elt as TouchMenuItem;
                    menu.IsMenuOpened = false;
                }
            }
        }

        protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            this.ShowMenu(this);
            e.Handled = true;
        }    
        
    }
}
